<?php
/**
 * 扔进回收站 - 支持批量
 * 
 * @author Cyrano
 * @since 2018-01-22
 */
class Attachment_Trash
{
    protected static $_res = array('status' => 0, 'msg' => '', 'data' => '');
    protected static $_capacity_trash = 0; // 预定义要删除内容的容量
    
    /**
     * 接口运行方法
     */
    public static function run($params)
    {
        $res = self::validate($params);
        if ($res['status'] == 0) {
            try {
                $timenow = Util_Timer::getMicrotime();
                $parent_folder = null; // 预定义要删除内容的父级目录信息
                
                /* 预处理文件 */
                if ($res['data']['attachments']) {
                    /* 校验文件 */
                    $attachment_ids = explode(',', $res['data']['attachments']);
                    $attachments = Attachment_Model_Content::instance()->fetchByPK($attachment_ids);
                    if (! empty($attachments)) {
                        foreach ($attachments as $k => $v) {
                            if ($v['userid'] != $res['data']['userid']) {
                                throw new Exception('请勿非法操作');
                                break;
                            }
                        }
                        
                        /* 获取父级目录信息 */
                        if ($attachments[0]['folder_hid']) {
                            $folder_hids = explode(':', $attachments[0]['folder_hid']);
                            $parent_fid = (int) $folder_hids[count($folder_hids) - 1];
                            $parent_folder = Attachment_Model_Folder::instance()->getFolderByFid($res['data']['userid'], $parent_fid);
                        }
                    }
                }
                
                /* 处理文件夹 */
                if ($res['data']['folders']) {
                    /* 获取文件夹信息 */
                    $folder_fids = explode(',', $res['data']['folders']);
                    foreach ($folder_fids as $k => $v) {
                        $folder_fids[$k] = (int) $v;
                    }
                    $where_folder = array('userid' => $res['data']['userid'], 'fid' => array('$in' => $folder_fids));
                    $folders = Attachment_Model_Folder::instance()->fetchByWhere($where_folder);
                    
                    if (! empty($folders)) {
                        /* 获取父级目录节点信息 */
                        $parent_hid = '0';
                        if (! empty($parent_folder)) {
                            $parent_hid = $parent_folder[0]['hid'];
                        } elseif ($folders[0]['parent_id'] > 0) {
                            $where_folder_parent = array('userid' => $res['data']['userid'], 'fid' => (int) $folders[0]['parent_id']);
                            $parent_folder = Attachment_Model_Folder::instance()->fetchByWhere($where_folder_parent);
                            if (! empty($parent_folder)) {
                                $parent_hid = $parent_folder[0]['hid'];
                            }
                        }
                        
                        /* 扔进回收站 - 顶级目录 */
                        self::_deleteFolder($folders, $parent_hid);
                        
                        /* 扔进回收站 - 子级项 */
                        self::_deleteFolderChildren($folders);
                    }
                }
                
                /* 处理文件 */
                if ($res['data']['attachments']) {
                    /* 扔进回收站 */
                    self::_deleteFile($attachments);
                }
                
                /* 处理父级目录的 is_has_children 字段及容量信息更新 */
                if (! empty($parent_folder)) {
                    /* 查询该目录下是否还有文件 */
                    $where_file_child = array('userid' => $res['data']['userid'], 'folder_hid' => $parent_folder[0]['hid'], 'status' => 1);
                    $count_file_child = Attachment_Model_Content::instance()->getCount($where_file_child);
                    
                    /* 查询该目录下是否还有文件夹 */
                    $where_folder_child = array('userid' => $res['data']['userid'], 'parent_id' => $parent_folder[0]['fid'], 'status' => 1);
                    $count_folder_child = Attachment_Model_Folder::instance()->getCount($where_folder_child);
                    
                    /* 预定义要更新的内容 */
                    $set_parent_folder = array();
                    
                    /* 处理 is_has_children 字段 */
                    if ($count_file_child == 0 && $count_folder_child == 0) {
                        $set_parent_folder['is_has_children'] = 0;
                    }
                    
                    /* 处理容量 */
                    if (self::$_capacity_trash > 0) {
                        $folder_size = $parent_folder[0]['folder_size'] - self::$_capacity_trash;
                        $set_parent_folder['folder_size'] = $folder_size > 0 ? $folder_size : 0;
                    }
                    
                    /* 执行更新 */
                    if (! empty($set_parent_folder)) {
                        $set_parent_folder['mtime'] = $timenow;
                        Attachment_Model_Folder::instance()->updateForEntity($set_parent_folder, $parent_folder[0]['_id']);
                    }
                }
            } catch (Exception $e) {
                $res['status'] = 1;
                $res['msg'] = '删除失败。错误信息：' . $e->getMessage();
            }
        }
        
        /* 返回数据过滤 */
        $res['data'] = '';
        
        return $res;
    }
    
    /**
     * 验证参数
     */
    private static function validate($params)
    {
        try {
            /* 校验参数 */
            if (! isset($params['userid']) || ! $params['userid']) {
                throw new Exception('参数 userid 未提供');
            }
            if (! isset($params['folders']) || ! $params['folders']) {
                $params['folders'] = '';
            }
            if (! isset($params['attachments']) || ! $params['attachments']) {
                $params['attachments'] = '';
            }
            
            self::$_res['data'] = $params;
        } catch (Exception $e) {
            self::$_res['status'] = 1;
            self::$_res['msg'] = $e->getMessage();
        }
        
        return self::$_res;
    }
    
    /**
     * 递归删除指定文件夹下的子项
     * 
     * @param array $target_folder 要删除的目标目录
     */
    private static function _deleteFolderChildren($target_folder)
    {
        if (! empty($target_folder)) {
            foreach ($target_folder as $k => $v) {
                /* 查询子级文件夹，并执行删除 */
                $where_folder = array('parent_id' => $v['fid'], 'userid' => $v['userid']);
                $folders = Attachment_Model_Folder::instance()->fetchByWhere($where_folder);
                if (! empty($folders)) {
                    /* 删除该子级文件夹 */
                    self::_deleteFolder($folders, $v['hid']);
                    
                    /* 递归删除子孙级项 */
                    foreach ($folders as $kk => $vv) {
                        if ($vv['is_has_children'] == 1) {
                            $child_folder[0] = $vv; // 补齐为二维数组
                            self::_deleteFolderChildren($child_folder);
                        }
                    }
                }
                
                /* 查询子级文件，并执行删除 */
                $where_file = array('userid' => $v['userid'], 'folder_hid' => $v['hid']);
                $files = Attachment_Model_Content::instance()->fetchByWhere($where_file);
                self::_deleteFile($files);
            }
        }
    }
    
    /**
     * 删除指定文件夹
     * 
     * @param array $folders 要删除的文件夹
     */
    private static function _deleteFolder($folders, $parent_hid)
    {
        if (! empty($folders) && is_array($folders)) {
            $timenow = Util_Timer::getMicrotime();
            
            /* 处理文件夹节点路径名称 */
            $path_name = Attachment_Folder::getPathName($folders[0]['userid'], $folders[0]['hid']);
            $path_name_json = json_encode(array('path_name' => $path_name), JSON_UNESCAPED_UNICODE);
            $path_name_json = str_replace("\\/", "/", $path_name_json);
            
            /* 更新文件夹信息 */
            foreach ($folders as $k => $v) {
                $set_folder = array(
                        'extra' => $path_name_json,
                        'status' => -1, 
                        'mtime' => $timenow
                );
                Attachment_Model_Folder::instance()->updateForEntity($set_folder, $v['_id']);
            }
            
            /* 更新文件夹同名处理表及删除容量信息 */
            foreach ($folders as $k => $v) {
                Attachment_Juna::deleteCopyNums($v['userid'], $v['title'], 2, $parent_hid);
                self::$_capacity_trash += $v['folder_size'];
            }
        }
    }
    
    /**
     * 删除指定文件
     * 
     * @param array $files 要删除的文件
     */
    private static function _deleteFile($files)
    {
        if (! empty($files) && is_array($files)) {
            $timenow = Util_Timer::getMicrotime();
            
            /* 处理文件 ID */
            $attachment_ids = array();
            foreach ($files as $k => $v) {
                $attachment_ids[] = new MongoId($v['_id']);
            }
            
            /* 处理文件节点路径名称 */
            $path_name = Attachment_File::getPathName($files[0]['userid'], $files[0]['folder_hid']);
            $path_name_json = json_encode(array('path_name' => $path_name), JSON_UNESCAPED_UNICODE);
            $path_name_json = str_replace("\\/", "/", $path_name_json);
            
            /* 更新文件信息 */
            $set_attachment = array(
                    'extra' => $path_name_json, 
                    'status' => -1, 
                    'mtime' => $timenow
            );
            $where_attachment = array('_id' => array('$in' => $attachment_ids));
            Attachment_Model_Content::instance()->update($set_attachment, $where_attachment);
            
            /* 更新文件同名处理表及删除容量信息 */
            foreach ($files as $k => $v) {
                Attachment_Juna::deleteCopyNums($v['userid'], $v['title'], 1, $v['folder_hid']);
                self::$_capacity_trash += $v['filesize'];
            }
        }
    }
}
